﻿using UnityEngine;
using System.Collections;

public struct SolverWorkArea
{
    public Vector3 deltaVelocity;
    public SolverWorkArea(Vector3 v)
    {
        deltaVelocity = v;
    }
    public void Clear()
    {
        deltaVelocity = Vector3.zero;
    }
}

/// <summary>
/// 刚体和碰撞体的融合对象
/// </summary>
public class PhysicCollider : MonoBehaviour {
    public enum ColliderType
    {
        Sphere,
        DynamicMesh,
    }

    public bool UseGravity = false;
    public float Mass = 1;
    public float restitutionCoeff = 1;

    //position 使用Transform中存储
    //public Vector3 velocity = Vector3.zero;
    public Vector3 force = Vector3.zero;
    public float invMass;
    public ColliderType colliderType;
    public SolverWorkArea solverWorkArea = new SolverWorkArea();
    public float Friction = 0.01f;
    public float Restitution = 1;

    public bool IsCollision = false;
    public Vector3 lastPosition;

    public bool IsFixed = false; //是否固定位置 fixed 之间不碰撞计算
    protected virtual void Awake()
    {
        if (Mass == 0)
        {
            invMass = 0;
        }
        else
        {
            invMass = 1 / Mass;
        }
        if(UseGravity)
        {
            force = new Vector3(0, -9.8f, 0);
        }
        lastPosition = transform.position;
    }

    protected Vector3 accelerate;
    public virtual void UpdateVelocity()
    {
        //velocity += invMass * Time.fixedDeltaTime * force;

    }

    public virtual void CorrectVelocity()
    {
        //velocity += solverWorkArea.deltaVelocity;
    }

    public Vector3 GetVelocity()
    {
        return transform.position - lastPosition;
    }

    public virtual void AccumulateForces()
    {
        accelerate = force * invMass;
    }
    public virtual void UpdatePosition()
    {
        var curPos = transform.position;
        //var a = force * invMass + solverWorkArea.deltaVelocity;
        var newPos = (2) * curPos - (1)*lastPosition + accelerate * Time.fixedDeltaTime * Time.fixedDeltaTime;
        lastPosition = curPos;
        transform.position = newPos;
        //transform.position += Time.fixedDeltaTime * velocity;
    }
    public virtual void ApplyImpulse(Vector3 impulse, Vector3 relativePos)
    {
        solverWorkArea.deltaVelocity += invMass * impulse;
    }

    public virtual void ApplyContact(PhysicContact contact)
    {

    }
    public virtual void Clear()
    {

    }
}
